home *** CD-ROM | disk | FTP | other *** search
- // Copyright ⌐ 1997 Mario M. Westphal
- // All Rights reserved
- // This source code is only intended as a supplement to the
- // Sort Solution user documentation and related
- // electronic documentation provided with the library.
- // See these sources for detailed information regarding the
- // Sort Solution product.
-
- // ** See OnBtnExec() for integration details **
- //
-
- #include "stdafx.h"
- #include "mfcsmpl.h"
- #include "mfcsmplDlg.h"
-
- #ifdef _DEBUG
- #define new DEBUG_NEW
- #undef THIS_FILE
- static char THIS_FILE[] = __FILE__;
- #endif
-
- // This application is used to edit the profile
- const TCHAR APP_NAME[] = _T("Notepad ");
-
-
- /////////////////////////////////////////////////////////////////////////////
- // CAboutDlg dialog used for App About
- class CAboutDlg : public CDialog
- {
- public:
- CAboutDlg();
-
- // Dialog Data
- //{{AFX_DATA(CAboutDlg)
- enum { IDD = IDD_ABOUTBOX };
- //}}AFX_DATA
-
- // ClassWizard generated virtual function overrides
- //{{AFX_VIRTUAL(CAboutDlg)
- protected:
- virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
- //}}AFX_VIRTUAL
-
- // Implementation
- protected:
- //{{AFX_MSG(CAboutDlg)
- //}}AFX_MSG
- DECLARE_MESSAGE_MAP()
- };
-
- CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
- {
- //{{AFX_DATA_INIT(CAboutDlg)
- //}}AFX_DATA_INIT
- }
-
- void CAboutDlg::DoDataExchange(CDataExchange* pDX)
- {
- CDialog::DoDataExchange(pDX);
- //{{AFX_DATA_MAP(CAboutDlg)
- //}}AFX_DATA_MAP
- }
-
- BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
- //{{AFX_MSG_MAP(CAboutDlg)
- // No message handlers
- //}}AFX_MSG_MAP
- END_MESSAGE_MAP()
-
-
-
- /////////////////////////////////////////////////////////////////////////////
- // Callback for the Sort Solution DLL
- // This callback updates the progress controls to give the user some feedback
- // about the current state of the sort
- BOOL CALLBACK NotifyCallback(UINT Code, DWORD Status, DWORD Extra)
- {
- CMfcsmplDlg* pdlg = (CMfcsmplDlg*)Extra;
-
- switch (Code)
- {
- case SORTSOL_NOTIFY_SORTPERCENTAGE:
- VERIFY(pdlg->m_Progress_Sort.PostMessage(PBM_SETPOS, (int)Status, 0L));
- break;
-
- case SORTSOL_NOTIFY_MERGEPERCENTAGE:
- VERIFY(pdlg->m_Progress_Merge.PostMessage(PBM_SETPOS, (int)Status, 0L));
- break;
-
- case SORTSOL_NOTIFY_BEGINSORT:
- switch (Status) {
- case SORTSOL_STATUS_ONEPHASESORT:
- break;
- case SORTSOL_STATUS_MERGESORT:
- break;
- }
- break;
-
- case SORTSOL_NOTIFY_FINISHSORT:
- break;
-
- case SORTSOL_NOTIFY_BEGINMERGE:
- break;
-
- case SORTSOL_NOTIFY_FINISHMERGE:
- break;
-
- case SORTSOL_NOTIFY_FINISHED:
- break;
- }
-
- // A simple way to keep the application responding
- MSG msg;
- while (::PeekMessage( &msg, NULL, 0, 0, PM_NOREMOVE)) {
- AfxGetApp()->PumpMessage();
- }
-
- // Continue with sort while m_Running remains true
- // m_Running will be set to FALSE if the user aborts the sort
- return pdlg->IsRunning();
- }
-
-
-
- /////////////////////////////////////////////////////////////////////////////
- // CMfcsmplDlg dialog
- CMfcsmplDlg::CMfcsmplDlg(CWnd* pParent /*=NULL*/)
- : CDialog(CMfcsmplDlg::IDD, pParent)
- {
- //{{AFX_DATA_INIT(CMfcsmplDlg)
- m_Static_BytesSorted = _T("0");
- m_Static_OutputFile = _T("");
- m_Static_LogFile = _T("");
- m_Static_RecsSorted = _T("0");
- m_Static_Time = _T("?");
- m_Static_RecsFiltered = _T("0");
- //}}AFX_DATA_INIT
- // Note that LoadIcon does not require a subsequent DestroyIcon in Win32
- m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
-
-
- // Some additional initializations
- m_Running = FALSE;
- }
-
-
- /////////////////////////////////////////////////////////////////////////////
- //
- void CMfcsmplDlg::DoDataExchange(CDataExchange* pDX)
- {
- CDialog::DoDataExchange(pDX);
- //{{AFX_DATA_MAP(CMfcsmplDlg)
- DDX_Control(pDX, IDC_BTN_EDIT, m_Btn_Edit);
- DDX_Control(pDX, IDC_EDIT_FILENAME, m_Edit_FileName);
- DDX_Control(pDX, IDCANCEL, m_Btn_Cancel);
- DDX_Control(pDX, IDC_PROGRESS_SORT, m_Progress_Sort);
- DDX_Control(pDX, IDC_PROGRESS_MERGE, m_Progress_Merge);
- DDX_Control(pDX, IDC_BTN_EXEC, m_Btn_Exec);
- DDX_Control(pDX, IDC_BTN_BROWSE, m_Btn_Browse);
- DDX_Text(pDX, IDC_STATIC_BYTESSORTED, m_Static_BytesSorted);
- DDX_Text(pDX, IDC_STATIC_OUTPUTFILE, m_Static_OutputFile);
- DDX_Text(pDX, IDC_STATIC_LOGFILE, m_Static_LogFile);
- DDX_Text(pDX, IDC_STATIC_RECSSORTED, m_Static_RecsSorted);
- DDX_Text(pDX, IDC_STATIC_TIME, m_Static_Time);
- DDX_Text(pDX, IDC_STATIC_RECSFILTERED, m_Static_RecsFiltered);
- //}}AFX_DATA_MAP
- }
-
-
- BEGIN_MESSAGE_MAP(CMfcsmplDlg, CDialog)
- //{{AFX_MSG_MAP(CMfcsmplDlg)
- ON_WM_SYSCOMMAND()
- ON_WM_PAINT()
- ON_WM_QUERYDRAGICON()
- ON_BN_CLICKED(IDC_BTN_BROWSE, OnBtnBrowse)
- ON_BN_CLICKED(IDC_BTN_EXEC, OnBtnExec)
- ON_EN_CHANGE(IDC_EDIT_FILENAME, OnChangeEditFilename)
- ON_BN_CLICKED(IDC_BTN_EDIT, OnBtnEdit)
- //}}AFX_MSG_MAP
- END_MESSAGE_MAP()
-
-
- /////////////////////////////////////////////////////////////////////////////
- //
- BOOL CMfcsmplDlg::OnInitDialog()
- {
- CDialog::OnInitDialog();
-
- ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
- ASSERT(IDM_ABOUTBOX < 0xF000);
-
- CMenu* pSysMenu = GetSystemMenu(FALSE);
- if (pSysMenu != NULL)
- {
- CString strAboutMenu;
- strAboutMenu.LoadString(IDS_ABOUTBOX);
- if (!strAboutMenu.IsEmpty())
- {
- pSysMenu->AppendMenu(MF_SEPARATOR);
- pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
- }
- }
-
- SetIcon(m_hIcon, TRUE); // Set big icon
- SetIcon(m_hIcon, FALSE); // Set small icon
-
- m_Btn_Exec.EnableWindow(FALSE);
- m_Progress_Sort.SetRange(0,100);
- m_Progress_Merge.SetRange(0,100);
- m_Btn_Edit.EnableWindow(FALSE);
-
- return TRUE; // return TRUE unless you set the focus to a control
- }
-
-
- /////////////////////////////////////////////////////////////////////////////
- //
- void CMfcsmplDlg::OnSysCommand(UINT nID, LPARAM lParam)
- {
- if ((nID & 0xFFF0) == IDM_ABOUTBOX)
- {
- CAboutDlg dlgAbout;
- dlgAbout.DoModal();
- }
- else
- {
- CDialog::OnSysCommand(nID, lParam);
- }
- }
-
-
- /////////////////////////////////////////////////////////////////////////////
- // If you add a minimize button to your dialog, you will need the code below
- // to draw the icon. For MFC applications using the document/view model,
- // this is automatically done for you by the framework.
- void CMfcsmplDlg::OnPaint()
- {
- if (IsIconic())
- {
- CPaintDC dc(this); // device context for painting
-
- SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);
-
- // Center icon in client rectangle
- int cxIcon = GetSystemMetrics(SM_CXICON);
- int cyIcon = GetSystemMetrics(SM_CYICON);
- CRect rect;
- GetClientRect(&rect);
- int x = (rect.Width() - cxIcon + 1) / 2;
- int y = (rect.Height() - cyIcon + 1) / 2;
-
- // Draw the icon
- dc.DrawIcon(x, y, m_hIcon);
- }
- else
- {
- CDialog::OnPaint();
- }
- }
-
-
- /////////////////////////////////////////////////////////////////////////////
- // The system calls this to obtain the cursor to display while the user drags
- // the minimized window.
- HCURSOR CMfcsmplDlg::OnQueryDragIcon()
- {
- return (HCURSOR) m_hIcon;
- }
-
-
- /////////////////////////////////////////////////////////////////////////////
- // Only allow to exit the application when the sort is not running
- void CMfcsmplDlg::OnCancel()
- {
- if (m_Running) {
- CString strtab;
- VERIFY(strtab.LoadString(IDS_CLOSEINFO));
- AfxMessageBox(strtab,MB_ICONEXCLAMATION | MB_OK);
- return;
- }
- CDialog::OnCancel();
- }
-
-
- /////////////////////////////////////////////////////////////////////////////
- // Display a file open common control
- void CMfcsmplDlg::OnBtnBrowse()
- {
- CString strtab;
- VERIFY(strtab.LoadString(IDS_FILEMASK));
- CFileDialog dlg(TRUE, _T("*.ssp"), NULL, OFN_OVERWRITEPROMPT,strtab);
-
- if (dlg.DoModal() == IDOK) {
- m_Edit_FileName.SetWindowText(dlg.GetPathName());
- }
- }
-
-
- /////////////////////////////////////////////////////////////////////////////
- // Display an error message for error code "Code"
- void CMfcsmplDlg::ShowErrorMessage(int Code)
- {
- CString msg;
- LPTSTR lpc = msg.GetBuffer(255);
- unsigned long len = 255;
- SSIGetErrorMessage(Code,lpc,&len);
- msg.ReleaseBuffer(-1);
- AfxMessageBox(msg,MB_ICONSTOP | MB_OK);
- }
-
-
- /////////////////////////////////////////////////////////////////////////////
- // This method handles both "Start" and "Stop".
- void CMfcsmplDlg::OnBtnExec()
- {
- // If the sort is running...
- if (m_Running) {
- // This will trigger the callback NotifyCallback() to return FALSE
- // the next time it it called from the sort DLL
- m_Running = FALSE;
- // Don't let the user press that button again until the sort is
- // stopped
- m_Btn_Exec.EnableWindow(FALSE);
- }
- else {
- m_Running = TRUE;
- // Disable the front end while the sort is running
- m_Btn_Cancel.EnableWindow(FALSE);
- m_Btn_Browse.EnableWindow(FALSE);
- m_Btn_Edit.EnableWindow(FALSE);
- // Change the button title
- CString strtab;
- VERIFY(strtab.LoadString(IDS_BTNSTOP));
- m_Btn_Exec.SetWindowText(strtab);
-
- // Update the front end
- m_Progress_Sort.SetPos(0);
- m_Progress_Merge.SetPos(0);
-
-
- // Update the dialog to display the new values
- m_Static_LogFile = _T("");
- m_Static_BytesSorted = _T("0");
- m_Static_RecsSorted = _T("0");
- m_Static_RecsFiltered = _T("0");
- m_Static_Time = _T("?");
- UpdateData(FALSE);
-
- // Setup the profile status. Since we don't want to
- // override any of the commands from the profile,
- // we zero it out
- // Don't forget to initialize the size member
- SORTSOL_CMDFILESTATUS cmdstat;
- memset(&cmdstat,0,sizeof(cmdstat));
- cmdstat.uSize = sizeof(cmdstat);
-
- // Setup the stats structure. Zero it out and
- // intitialize the uSize member
- SORTSOL_STATS stats;
- memset(&stats,0x0,sizeof(stats));
- stats.uSize = sizeof(stats);
-
- // Now create a new sort instance. This step will read the command
- // file, check it for validity and return some information in "cmdstat"
- int res;
- SSIH ssihandle;
-
- // Get the profile name from the dialog
- CString profile;
- m_Edit_FileName.GetWindowText(profile);
- res = SSICreateFromFile(&ssihandle, profile, &cmdstat);
-
- if (res == SOSOERR_SUCCESS) {
- // Display some of the information contained in cmdstat
- m_Static_OutputFile = cmdstat.OutputFileName;
- m_Static_LogFile = cmdstat.LogFileName;
- UpdateData(FALSE);
-
- // Register the callback function
- SSIRegisterCallback(ssihandle,NotifyCallback,(DWORD)this);
-
- // Let the sort do it's work...
- res = SSISort(ssihandle);
-
- // If everything went fine, get the stats. We will use this
- // information a bit later to display some statistical information
- if (res == SOSOERR_SUCCESS) {
- SSIGetStats(ssihandle, &stats);
- }
-
- // Free the sort instance. This will reclaim all memory and
- // other resources used by the sort
- SSIFree(ssihandle);
- }
-
- // If we have an error condition, display an appropriate message
- if (res != SOSOERR_SUCCESS) {
- ShowErrorMessage(res);
- }
- else {
- // Display the stats
- TCHAR ac[100];
- sprintf(ac,_T("%I64d"),stats.liBytesSorted);
- m_Static_BytesSorted = ac;
-
- sprintf(ac,_T("%I64d"),stats.liRecordsProcessed);
- m_Static_RecsSorted = ac;
-
- sprintf(ac,_T("%I64d"),stats.liRecordsFiltered);
- m_Static_RecsFiltered = ac;
-
- m_Static_Time.Format(_T("%u s"),(stats.dwSortTime+stats.dwMergeTime)/1000);
-
- UpdateData(FALSE);
-
- // And we're finished!
- CString strtab1,strtitle;
- VERIFY(strtab.LoadString(IDS_SORTCOMPLETED));
- VERIFY(strtitle.LoadString(IDS_SOSO_TITLE));
-
- MessageBox(strtab,strtitle,MB_ICONEXCLAMATION | MB_OK);
- }
-
- // Reactivate the front end...
- m_Running = FALSE;
- m_Btn_Cancel.EnableWindow(TRUE);
- m_Btn_Exec.EnableWindow(TRUE);
- VERIFY(strtab.LoadString(IDS_BTNEXEC));
- m_Btn_Exec.SetWindowText(strtab);
- m_Btn_Browse.EnableWindow(TRUE);
- m_Btn_Edit.EnableWindow(TRUE);
- }
- }
-
-
- /////////////////////////////////////////////////////////////////////////////
- // Active/Deactivate the buttons depending on the content of the edit field
- void CMfcsmplDlg::OnChangeEditFilename()
- {
- CString s;
- m_Edit_FileName.GetWindowText(s);
- m_Btn_Exec.EnableWindow(!s.IsEmpty());
- m_Btn_Edit.EnableWindow(!s.IsEmpty());
- }
-
-
- /////////////////////////////////////////////////////////////////////////////
- // Launch Notepad to allow the user to edit the profile
- // - cheap but working
- void CMfcsmplDlg::OnBtnEdit()
- {
- CString filename;
- m_Edit_FileName.GetWindowText(filename);
-
-
- WinExec(APP_NAME + filename,SW_SHOWNORMAL);
- }
-